<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>珠峰架构师成长计划</title>
    <link rel="stylesheet" type="text/css" href="../static/css/main.css">
</head>
<body>
<div class="nav">
    <div class="logo">
        
            珠峰架构师成长计划
        
    </div>
<ul><li><a href="../index.html">0.Async</a></li><li><a href="../html/0.editor.html">0.editor</a></li><li><a href="../html/0.module.html">0.module</a></li><li><a href="../html/1.ES2015.html">1.ES2015</a></li><li><a href="../html/2.Promise.html">2.Promise</a></li><li><a href="../html/3.Node.html">3.Node</a></li><li><a href="../html/4.NodeInstall.html">4.NodeInstall</a></li><li><a href="../html/5.REPL.html">5.REPL</a></li><li><a href="../html/6.NodeCore.html">6.NodeCore</a></li><li><a href="../html/7.module&NPM.html">7.module&NPM</a></li><li><a href="../html/8.Encoding.html">8.Encoding</a></li><li><a href="../html/9.Buffer.html">9.Buffer</a></li><li><a href="../html/10.fs.html">10.fs</a></li><li><a href="../html/11.Stream-1.html">11.Stream-1</a></li><li><a href="../html/11.Stream-2.html">11.Stream-2</a></li><li><a href="../html/11.Stream-3.html">11.Stream-3</a></li><li><a href="../html/11.Stream-4.html">11.Stream-4</a></li><li><a href="../html/12-Network-2.html">12-Network-2</a></li><li><a href="../html/12.NetWork-3.html">12.NetWork-3</a></li><li><a href="../html/12.Network-1.html">12.Network-1</a></li><li><a href="../html/13.tcp.html">13.tcp</a></li><li><a href="../html/14.http-1.html">14.http-1</a></li><li><a href="../html/14.http-2.html">14.http-2</a></li><li><a href="../html/15.compress.html">15.compress</a></li><li><a href="../html/16.crypto.html">16.crypto</a></li><li><a href="../html/17.process.html">17.process</a></li><li><a href="../html/18.yargs.html">18.yargs</a></li><li><a href="../html/19.cache.html">19.cache</a></li><li><a href="../html/20.action.html">20.action</a></li><li><a href="../html/21.https.html">21.https</a></li><li><a href="../html/22.cookie.html">22.cookie</a></li><li><a href="../html/23.session.html">23.session</a></li><li><a href="../html/24.express-1.html">24.express-1</a></li><li><a href="../html/24.express-2.html">24.express-2</a></li><li><a href="../html/24.express-3.html">24.express-3</a></li><li><a href="../html/24.express-4.html">24.express-4</a></li><li><a href="../html/25.koa-1.html">25.koa-1</a></li><li><a href="../html/26.webpack-1-basic.html">26.webpack-1-basic</a></li><li><a href="../html/26.webpack-2-optimize.html">26.webpack-2-optimize</a></li><li><a href="../html/26.webpack-3.tapable.html">26.webpack-3.tapable</a></li><li><a href="../html/26.webpack-4-AST.html">26.webpack-4-AST</a></li><li><a href="../html/26.webpack-5-source.html">26.webpack-5-source</a></li><li><a href="../html/26.webpack-6-loader.html">26.webpack-6-loader</a></li><li><a href="../html/26.webpack-7-plugin.html">26.webpack-7-plugin</a></li><li><a href="../html/26.webpack-8-hand.html">26.webpack-8-hand</a></li><li><a href="../html/27.react-1.html">27.react-1</a></li><li><a href="../html/27.react-2.html">27.react-2</a></li><li><a href="../html/27.react-3.html">27.react-3</a></li><li><a href="../html/27.react-4-immutable.html">27.react-4-immutable</a></li><li><a href="../html/27.react-5-react-dom-diff.html">27.react-5-react-dom-diff</a></li><li><a href="../html/27.react-6.html">27.react-6</a></li><li><a href="../html/28.react-mobx.html">28.react-mobx</a></li><li><a href="../html/28.redux-0.html">28.redux-0</a></li><li><a href="../html/28.redux-1.html">28.redux-1</a></li><li><a href="../html/28.redux-2-中间件.html">28.redux-2-中间件</a></li><li><a href="../html/28.redux-3-saga.html">28.redux-3-saga</a></li><li><a href="../html/28.redux-jwt-back.html">28.redux-jwt-back</a></li><li><a href="../html/28.redux-jwt-front.html">28.redux-jwt-front</a></li><li><a href="../html/29.mongodb-1.html">29.mongodb-1</a></li><li><a href="../html/29.mongodb-2.html">29.mongodb-2</a></li><li><a href="../html/29.mongodb-3.html">29.mongodb-3</a></li><li><a href="../html/29.mongodb-4.html">29.mongodb-4</a></li><li><a href="../html/29.mongodb-5.html">29.mongodb-5</a></li><li><a href="../html/29.mongodb-6.html">29.mongodb-6</a></li><li><a href="../html/30.cms-1-mysql.html">30.cms-1-mysql</a></li><li><a href="../html/30.cms-2-mysql.html">30.cms-2-mysql</a></li><li><a href="../html/30.cms-3-mysql.html">30.cms-3-mysql</a></li><li><a href="../html/30.cms-4-egg.html">30.cms-4-egg</a></li><li><a href="../html/30.cms-5-api.html">30.cms-5-api</a></li><li><a href="../html/30.cms-6-roadhog.html">30.cms-6-roadhog</a></li><li><a href="../html/30.cms-7-umi.html">30.cms-7-umi</a></li><li><a href="../html/30.cms-8-dva.html">30.cms-8-dva</a></li><li><a href="../html/30.cms-9-dva.html">30.cms-9-dva</a></li><li><a href="../html/30.cms-10-front.html">30.cms-10-front</a></li><li><a href="../html/30.cms-11-deploy.html">30.cms-11-deploy</a></li><li><a href="../html/33.redis.html">33.redis</a></li><li><a href="../html/34.unittest.html">34.unittest</a></li><li class="active"><a href="../html/35.jwt.html">35.jwt</a></li><li><a href="../html/36.websocket-1.html">36.websocket-1</a></li><li><a href="../html/36.websocket-2.html">36.websocket-2</a></li><li><a href="../html/38.chat-api-1.html">38.chat-api-1</a></li><li><a href="../html/38.chat-api-2.html">38.chat-api-2</a></li><li><a href="../html/38.chat-3.html">38.chat-3</a></li><li><a href="../html/38.chat-api-3.html">38.chat-api-3</a></li><li><a href="../html/38.chat.html">38.chat</a></li><li><a href="../html/38.chat2.html">38.chat2</a></li><li><a href="../html/38.chat2.html">38.chat2</a></li><li><a href="../html/39.crawl-0.html">39.crawl-0</a></li><li><a href="../html/39.crawl-1.html">39.crawl-1</a></li><li><a href="../html/39.crawl-2.html">39.crawl-2</a></li><li><a href="../html/40.deploy.html">40.deploy</a></li><li><a href="../html/41.safe.html">41.safe</a></li><li><a href="../html/42.test.html">42.test</a></li><li><a href="../html/43.nginx.html">43.nginx</a></li><li><a href="../html/44.enzyme.html">44.enzyme</a></li><li><a href="../html/45.docker.html">45.docker</a></li><li><a href="../html/46.elastic.html">46.elastic</a></li><li><a href="../html/47.oauth.html">47.oauth</a></li><li><a href="../html/48.wxpay.html">48.wxpay</a></li><li><a href="../html/49.nunjucks.html">49.nunjucks</a></li><li><a href="../html/50.ketang.html">50.ketang</a></li><li><a href="../html/index.html">index</a></li><li><a href="../html/51.typescript.html">51.typescript</a></li><li><a href="../html/52.UML.html">52.UML</a></li><li><a href="../html/53.design.html">53.design</a></li><li><a href="../html/index.html">index</a></li><li><a href="../html/54.linux.html">54.linux</a></li><li><a href="../html/55.yaml.html">55.yaml</a></li><li><a href="../html/50.ketang2.html">50.ketang2</a></li><li><a href="../html/56.ts.html">56.ts</a></li><li><a href="../html/57.ts_react.html">57.ts_react</a></li><li><a href="../html/58.react-ssr.html">58.react-ssr</a></li><li><a href="../html/59.react-ssr.html">59.react-ssr</a></li></ul></div>


<div class="warpper">

    <div class="page-toc">
        <ul><li><a href="#t01.JWT">1.JWT</a></li><li><a href="#t12.主要应用场景">2.主要应用场景</a></li><li><a href="#t23.JWT的结构">3.JWT的结构</a><ul><li><a href="#t33.1 Header">3.1 Header</a></li><li><a href="#t43.2 Payload">3.2 Payload</a><ul><li><a href="#t53.2.1 标准中注册的声明 (建议但不强制使用)">3.2.1 标准中注册的声明 (建议但不强制使用)</a></li><li><a href="#t63.2.2 公共的声明">3.2.2 公共的声明</a></li><li><a href="#t73.2.3 私有的声明">3.2.3 私有的声明</a></li><li><a href="#t83.2.4  负载使用的例子">3.2.4  负载使用的例子</a></li></ul></li><li><a href="#t93.3 Signature">3.3 Signature</a></li></ul></li><li><a href="#t104.如何使用JWT">4.如何使用JWT</a></li><li><a href="#t115. JWT实战">5. JWT实战</a><ul><li><a href="#t125.1 config.js">5.1 config.js</a></li><li><a href="#t135.2 app.js">5.2 app.js</a></li><li><a href="#t145.3 jwt.js">5.3 jwt.js</a></li><li><a href="#t155.4 user.js">5.4 user.js</a></li></ul></li><li><a href="#t166. 前端">6. 前端</a><ul><li><a href="#t176.1 index.js">6.1 index.js</a></li><li><a href="#t186.2 api.js">6.2 api.js</a></li><li><a href="#t196.3 Login.js">6.3 Login.js</a></li><li><a href="#t206.4 User.js">6.4 User.js</a></li></ul></li><li><a href="#t217.原理实现">7.原理实现</a></li></ul>
    </div>
    
    <div class="content markdown-body">
        <h2 id="t01.JWT">1.JWT <a href="#t01.JWT"> # </a></h2>
<ul>
<li>JWT(json web token)&#x662F;&#x4E3A;&#x4E86;&#x5728;&#x7F51;&#x7EDC;&#x5E94;&#x7528;&#x73AF;&#x5883;&#x95F4;&#x4F20;&#x9012;&#x58F0;&#x660E;&#x800C;&#x6267;&#x884C;&#x7684;&#x4E00;&#x79CD;&#x57FA;&#x4E8E;JSON&#x7684;&#x5F00;&#x653E;&#x6807;&#x51C6;&#x3002;</li>
<li>JWT&#x7684;&#x58F0;&#x660E;&#x4E00;&#x822C;&#x88AB;&#x7528;&#x6765;&#x5728;&#x8EAB;&#x4EFD;&#x63D0;&#x4F9B;&#x8005;&#x548C;&#x670D;&#x52A1;&#x63D0;&#x4F9B;&#x8005;&#x95F4;&#x4F20;&#x9012;&#x88AB;&#x8BA4;&#x8BC1;&#x7684;&#x7528;&#x6237;&#x8EAB;&#x4EFD;&#x4FE1;&#x606F;&#xFF0C;&#x4EE5;&#x4FBF;&#x4E8E;&#x4ECE;&#x8D44;&#x6E90;&#x670D;&#x52A1;&#x5668;&#x83B7;&#x53D6;&#x8D44;&#x6E90;&#x3002;&#x6BD4;&#x5982;&#x7528;&#x5728;&#x7528;&#x6237;&#x767B;&#x5F55;&#x4E0A;&#x3002;</li>
<li>&#x56E0;&#x4E3A;&#x6570;&#x5B57;&#x7B7E;&#x540D;&#x7684;&#x5B58;&#x5728;&#xFF0C;&#x8FD9;&#x4E9B;&#x4FE1;&#x606F;&#x662F;&#x53EF;&#x4FE1;&#x7684;&#xFF0C;JWT&#x53EF;&#x4EE5;&#x4F7F;&#x7528;HMAC&#x7B97;&#x6CD5;&#x6216;&#x8005;&#x662F;RSA&#x7684;&#x516C;&#x79C1;&#x79D8;&#x94A5;&#x5BF9;&#x8FDB;&#x884C;&#x7B7E;&#x540D;</li>
</ul>
<h2 id="t12.&#x4E3B;&#x8981;&#x5E94;&#x7528;&#x573A;&#x666F;">2.&#x4E3B;&#x8981;&#x5E94;&#x7528;&#x573A;&#x666F; <a href="#t12.&#x4E3B;&#x8981;&#x5E94;&#x7528;&#x573A;&#x666F;"> # </a></h2>
<ul>
<li>&#x8EAB;&#x4EFD;&#x8BA4;&#x8BC1;&#x5728;&#x8FD9;&#x79CD;&#x573A;&#x666F;&#x4E0B;&#xFF0C;&#x4E00;&#x65E6;&#x7528;&#x6237;&#x5B8C;&#x6210;&#x4E86;&#x767B;&#x9646;&#xFF0C;&#x5728;&#x63A5;&#x4E0B;&#x6765;&#x7684;&#x6BCF;&#x4E2A;&#x8BF7;&#x6C42;&#x4E2D;&#x5305;&#x542B;JWT&#xFF0C;&#x53EF;&#x4EE5;&#x7528;&#x6765;&#x9A8C;&#x8BC1;&#x7528;&#x6237;&#x8EAB;&#x4EFD;&#x4EE5;&#x53CA;&#x5BF9;&#x8DEF;&#x7531;&#xFF0C;&#x670D;&#x52A1;&#x548C;&#x8D44;&#x6E90;&#x7684;&#x8BBF;&#x95EE;&#x6743;&#x9650;&#x8FDB;&#x884C;&#x9A8C;&#x8BC1;&#x3002;</li>
<li>&#x4FE1;&#x606F;&#x4EA4;&#x6362;&#x5728;&#x901A;&#x4FE1;&#x7684;&#x53CC;&#x65B9;&#x4E4B;&#x95F4;&#x4F7F;&#x7528;JWT&#x5BF9;&#x6570;&#x636E;&#x8FDB;&#x884C;&#x7F16;&#x7801;&#x662F;&#x4E00;&#x79CD;&#x975E;&#x5E38;&#x5B89;&#x5168;&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x7531;&#x4E8E;&#x5B83;&#x7684;&#x4FE1;&#x606F;&#x662F;&#x7ECF;&#x8FC7;&#x7B7E;&#x540D;&#x7684;&#xFF0C;&#x53EF;&#x4EE5;&#x786E;&#x4FDD;&#x53D1;&#x9001;&#x8005;&#x53D1;&#x9001;&#x7684;&#x4FE1;&#x606F;&#x662F;&#x6CA1;&#x6709;&#x7ECF;&#x8FC7;&#x4F2A;&#x9020;&#x7684;<h2 id="t23.JWT&#x7684;&#x7ED3;&#x6784;">3.JWT&#x7684;&#x7ED3;&#x6784; <a href="#t23.JWT&#x7684;&#x7ED3;&#x6784;"> # </a></h2>
JWT&#x5305;&#x542B;&#x4E86;&#x4F7F;&#x7528;<code>.</code>&#x5206;&#x9694;&#x7684;&#x4E09;&#x90E8;&#x5206;</li>
<li>Header &#x5934;&#x90E8;</li>
<li>Payload &#x8D1F;&#x8F7D;</li>
<li>Signature &#x7B7E;&#x540D;</li>
</ul>
<h3 id="t33.1 Header">3.1 Header <a href="#t33.1 Header"> # </a></h3>
<p>&#x5728;header&#x4E2D;&#x901A;&#x5E38;&#x5305;&#x542B;&#x4E86;&#x4E24;&#x90E8;&#x5206;&#xFF1A;token&#x7C7B;&#x578B;&#x548C;&#x91C7;&#x7528;&#x7684;&#x52A0;&#x5BC6;&#x7B97;&#x6CD5;&#x3002;</p>
<pre><code class="lang-json">{ <span class="hljs-attr">&quot;alg&quot;</span>: <span class="hljs-string">&quot;HS256&quot;</span>, <span class="hljs-attr">&quot;typ&quot;</span>: <span class="hljs-string">&quot;JWT&quot;</span>} 
</code></pre>
<p>&#x63A5;&#x4E0B;&#x6765;&#x5BF9;&#x8FD9;&#x90E8;&#x5206;&#x5185;&#x5BB9;&#x4F7F;&#x7528;<code>Base64Url</code>&#x7F16;&#x7801;&#x7EC4;&#x6210;&#x4E86;<code>JWT</code>&#x7ED3;&#x6784;&#x7684;&#x7B2C;&#x4E00;&#x90E8;&#x5206;&#x3002;</p>
<h3 id="t43.2 Payload">3.2 Payload <a href="#t43.2 Payload"> # </a></h3>
<p>&#x8D1F;&#x8F7D;&#x5C31;&#x662F;&#x5B58;&#x653E;&#x6709;&#x6548;&#x4FE1;&#x606F;&#x7684;&#x5730;&#x65B9;&#x3002;&#x8FD9;&#x4E2A;&#x540D;&#x5B57;&#x50CF;&#x662F;&#x6307;&#x8D27;&#x8F66;&#x4E0A;&#x627F;&#x8F7D;&#x7684;&#x8D27;&#x7269;&#xFF0C;&#x8FD9;&#x4E9B;&#x6709;&#x6548;&#x4FE1;&#x606F;&#x5305;&#x542B;&#x4E09;&#x4E2A;&#x90E8;&#x5206;</p>
<ul>
<li>&#x6807;&#x51C6;&#x4E2D;&#x6CE8;&#x518C;&#x7684;&#x58F0;&#x660E;</li>
<li>&#x516C;&#x5171;&#x7684;&#x58F0;&#x660E;</li>
<li>&#x79C1;&#x6709;&#x7684;&#x58F0;&#x660E;</li>
</ul>
<h4 id="t53.2.1 &#x6807;&#x51C6;&#x4E2D;&#x6CE8;&#x518C;&#x7684;&#x58F0;&#x660E; (&#x5EFA;&#x8BAE;&#x4F46;&#x4E0D;&#x5F3A;&#x5236;&#x4F7F;&#x7528;)">3.2.1 &#x6807;&#x51C6;&#x4E2D;&#x6CE8;&#x518C;&#x7684;&#x58F0;&#x660E; (&#x5EFA;&#x8BAE;&#x4F46;&#x4E0D;&#x5F3A;&#x5236;&#x4F7F;&#x7528;) <a href="#t53.2.1 &#x6807;&#x51C6;&#x4E2D;&#x6CE8;&#x518C;&#x7684;&#x58F0;&#x660E; (&#x5EFA;&#x8BAE;&#x4F46;&#x4E0D;&#x5F3A;&#x5236;&#x4F7F;&#x7528;)"> # </a></h4>
<ul>
<li>iss: jwt&#x7B7E;&#x53D1;&#x8005;</li>
<li>sub: jwt&#x6240;&#x9762;&#x5411;&#x7684;&#x7528;&#x6237;</li>
<li>aud: &#x63A5;&#x6536;jwt&#x7684;&#x4E00;&#x65B9;</li>
<li>exp: jwt&#x7684;&#x8FC7;&#x671F;&#x65F6;&#x95F4;&#xFF0C;&#x8FD9;&#x4E2A;&#x8FC7;&#x671F;&#x65F6;&#x95F4;&#x5FC5;&#x987B;&#x8981;&#x5927;&#x4E8E;&#x7B7E;&#x53D1;&#x65F6;&#x95F4;,&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x79D2;&#x6570;</li>
<li>nbf: &#x5B9A;&#x4E49;&#x5728;&#x4EC0;&#x4E48;&#x65F6;&#x95F4;&#x4E4B;&#x524D;&#xFF0C;&#x8BE5;jwt&#x90FD;&#x662F;&#x4E0D;&#x53EF;&#x7528;&#x7684;.</li>
<li>iat: jwt&#x7684;&#x7B7E;&#x53D1;&#x65F6;&#x95F4;</li>
</ul>
<h4 id="t63.2.2 &#x516C;&#x5171;&#x7684;&#x58F0;&#x660E;">3.2.2 &#x516C;&#x5171;&#x7684;&#x58F0;&#x660E; <a href="#t63.2.2 &#x516C;&#x5171;&#x7684;&#x58F0;&#x660E;"> # </a></h4>
<p>&#x516C;&#x5171;&#x7684;&#x58F0;&#x660E;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x4EFB;&#x4F55;&#x7684;&#x4FE1;&#x606F;&#xFF0C;&#x4E00;&#x822C;&#x6DFB;&#x52A0;&#x7528;&#x6237;&#x7684;&#x76F8;&#x5173;&#x4FE1;&#x606F;&#x6216;&#x5176;&#x4ED6;&#x4E1A;&#x52A1;&#x9700;&#x8981;&#x7684;&#x5FC5;&#x8981;&#x4FE1;&#x606F;.&#x4F46;&#x4E0D;&#x5EFA;&#x8BAE;&#x6DFB;&#x52A0;&#x654F;&#x611F;&#x4FE1;&#x606F;&#xFF0C;&#x56E0;&#x4E3A;&#x8BE5;&#x90E8;&#x5206;&#x5728;&#x5BA2;&#x6237;&#x7AEF;&#x53EF;&#x89E3;&#x5BC6;</p>
<h4 id="t73.2.3 &#x79C1;&#x6709;&#x7684;&#x58F0;&#x660E;">3.2.3 &#x79C1;&#x6709;&#x7684;&#x58F0;&#x660E; <a href="#t73.2.3 &#x79C1;&#x6709;&#x7684;&#x58F0;&#x660E;"> # </a></h4>
<p>&#x79C1;&#x6709;&#x58F0;&#x660E;&#x662F;&#x63D0;&#x4F9B;&#x8005;&#x548C;&#x6D88;&#x8D39;&#x8005;&#x6240;&#x5171;&#x540C;&#x5B9A;&#x4E49;&#x7684;&#x58F0;&#x660E;&#xFF0C;&#x4E00;&#x822C;&#x4E0D;&#x5EFA;&#x8BAE;&#x5B58;&#x653E;&#x654F;&#x611F;&#x4FE1;&#x606F;&#xFF0C;&#x56E0;&#x4E3A;base64&#x662F;&#x5BF9;&#x79F0;&#x89E3;&#x5BC6;&#x7684;&#xFF0C;&#x610F;&#x5473;&#x7740;&#x8BE5;&#x90E8;&#x5206;&#x4FE1;&#x606F;&#x53EF;&#x4EE5;&#x5F52;&#x7C7B;&#x4E3A;&#x660E;&#x6587;&#x4FE1;&#x606F;</p>
<h4 id="t83.2.4  &#x8D1F;&#x8F7D;&#x4F7F;&#x7528;&#x7684;&#x4F8B;&#x5B50;">3.2.4  &#x8D1F;&#x8F7D;&#x4F7F;&#x7528;&#x7684;&#x4F8B;&#x5B50; <a href="#t83.2.4  &#x8D1F;&#x8F7D;&#x4F7F;&#x7528;&#x7684;&#x4F8B;&#x5B50;"> # </a></h4>
<pre><code class="lang-js">{ <span class="hljs-string">&quot;sub&quot;</span>: <span class="hljs-string">&quot;1234567890&quot;</span>, <span class="hljs-string">&quot;name&quot;</span>: <span class="hljs-string">&quot;zfpx&quot;</span>, <span class="hljs-string">&quot;admin&quot;</span>: <span class="hljs-literal">true</span>} 
</code></pre>
<p>&#x4E0A;&#x8FF0;&#x7684;&#x8D1F;&#x8F7D;&#x9700;&#x8981;&#x7ECF;&#x8FC7;<code>Base64Url</code>&#x7F16;&#x7801;&#x540E;&#x4F5C;&#x4E3A;JWT&#x7ED3;&#x6784;&#x7684;&#x7B2C;&#x4E8C;&#x90E8;&#x5206;</p>
<h3 id="t93.3 Signature">3.3 Signature <a href="#t93.3 Signature"> # </a></h3>
<ul>
<li>&#x521B;&#x5EFA;&#x7B7E;&#x540D;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x7F16;&#x7801;&#x540E;&#x7684;header&#x548C;payload&#x4EE5;&#x53CA;&#x4E00;&#x4E2A;&#x79D8;&#x94A5;</li>
<li>&#x4F7F;&#x7528;header&#x4E2D;&#x6307;&#x5B9A;&#x7B7E;&#x540D;&#x7B97;&#x6CD5;&#x8FDB;&#x884C;&#x7B7E;&#x540D;</li>
<li>&#x4F8B;&#x5982;&#x5982;&#x679C;&#x5E0C;&#x671B;&#x4F7F;&#x7528;HMAC SHA256&#x7B97;&#x6CD5;&#xFF0C;&#x90A3;&#x4E48;&#x7B7E;&#x540D;&#x5E94;&#x8BE5;&#x4F7F;&#x7528;&#x4E0B;&#x5217;&#x65B9;&#x5F0F;&#x521B;&#x5EFA;<pre><code class="lang-js">HMACSHA256( base64UrlEncode(header) + <span class="hljs-string">&quot;.&quot;</span> + base64UrlEncode(payload), secret) 
</code></pre>
</li>
<li>&#x7B7E;&#x540D;&#x7528;&#x4E8E;&#x9A8C;&#x8BC1;&#x6D88;&#x606F;&#x7684;&#x53D1;&#x9001;&#x8005;&#x4EE5;&#x53CA;&#x6D88;&#x606F;&#x662F;&#x6CA1;&#x6709;&#x7ECF;&#x8FC7;&#x7BE1;&#x6539;&#x7684;</li>
<li>&#x5B8C;&#x6574;&#x7684;JWT &#x5B8C;&#x6574;&#x7684;JWT&#x683C;&#x5F0F;&#x7684;&#x8F93;&#x51FA;&#x662F;&#x4EE5;. &#x5206;&#x9694;&#x7684;&#x4E09;&#x6BB5;Base64&#x7F16;&#x7801;</li>
<li>&#x5BC6;&#x94A5;secret&#x662F;&#x4FDD;&#x5B58;&#x5728;&#x670D;&#x52A1;&#x7AEF;&#x7684;&#xFF0C;&#x670D;&#x52A1;&#x7AEF;&#x4F1A;&#x6839;&#x636E;&#x8FD9;&#x4E2A;&#x5BC6;&#x94A5;&#x8FDB;&#x884C;&#x751F;&#x6210;token&#x548C;&#x9A8C;&#x8BC1;&#xFF0C;&#x6240;&#x4EE5;&#x9700;&#x8981;&#x4FDD;&#x62A4;&#x597D;&#x3002;</li>
</ul>
<h2 id="t104.&#x5982;&#x4F55;&#x4F7F;&#x7528;JWT">4.&#x5982;&#x4F55;&#x4F7F;&#x7528;JWT <a href="#t104.&#x5982;&#x4F55;&#x4F7F;&#x7528;JWT"> # </a></h2>
<ol>
<li>&#x5F53;&#x7528;&#x6237;&#x4F7F;&#x7528;&#x5B83;&#x7684;&#x8BA4;&#x8BC1;&#x4FE1;&#x606F;&#x767B;&#x9646;&#x7CFB;&#x7EDF;&#x4E4B;&#x540E;&#xFF0C;&#x4F1A;&#x8FD4;&#x56DE;&#x7ED9;&#x7528;&#x6237;&#x4E00;&#x4E2A;JWT</li>
<li>&#x7528;&#x6237;&#x53EA;&#x9700;&#x8981;&#x672C;&#x5730;&#x4FDD;&#x5B58;&#x8BE5;token&#xFF08;&#x901A;&#x5E38;&#x4F7F;&#x7528;local storage&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;cookie&#xFF09;&#x5373;&#x53EF;</li>
<li>&#x5F53;&#x7528;&#x6237;&#x5E0C;&#x671B;&#x8BBF;&#x95EE;&#x4E00;&#x4E2A;&#x53D7;&#x4FDD;&#x62A4;&#x7684;&#x8DEF;&#x7531;&#x6216;&#x8005;&#x8D44;&#x6E90;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x901A;&#x5E38;&#x5E94;&#x8BE5;&#x5728;Authorization&#x5934;&#x90E8;&#x4F7F;&#x7528;Bearer&#x6A21;&#x5F0F;&#x6DFB;&#x52A0;JWT&#xFF0C;&#x5176;&#x5185;&#x5BB9;&#x770B;&#x8D77;&#x6765;&#x662F;&#x4E0B;&#x9762;&#x8FD9;&#x6837;<pre><code class="lang-js">Authorization: Bearer &lt;token&gt;
</code></pre>
</li>
<li>&#x56E0;&#x4E3A;&#x7528;&#x6237;&#x7684;&#x72B6;&#x6001;&#x5728;&#x670D;&#x52A1;&#x7AEF;&#x7684;&#x5185;&#x5B58;&#x4E2D;&#x662F;&#x4E0D;&#x5B58;&#x50A8;&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x8FD9;&#x662F;&#x4E00;&#x79CD;&#x65E0;&#x72B6;&#x6001;&#x7684;&#x8BA4;&#x8BC1;&#x673A;&#x5236;</li>
<li>&#x670D;&#x52A1;&#x7AEF;&#x7684;&#x4FDD;&#x62A4;&#x8DEF;&#x7531;&#x5C06;&#x4F1A;&#x68C0;&#x67E5;&#x8BF7;&#x6C42;&#x5934;Authorization&#x4E2D;&#x7684;JWT&#x4FE1;&#x606F;&#xFF0C;&#x5982;&#x679C;&#x5408;&#x6CD5;&#xFF0C;&#x5219;&#x5141;&#x8BB8;&#x7528;&#x6237;&#x7684;&#x884C;&#x4E3A;&#x3002;</li>
<li>&#x7531;&#x4E8E;JWT&#x662F;&#x81EA;&#x5305;&#x542B;&#x7684;&#xFF0C;&#x56E0;&#x6B64;&#x51CF;&#x5C11;&#x4E86;&#x9700;&#x8981;&#x67E5;&#x8BE2;&#x6570;&#x636E;&#x5E93;&#x7684;&#x9700;&#x8981;</li>
<li>JWT&#x7684;&#x8FD9;&#x4E9B;&#x7279;&#x6027;&#x4F7F;&#x5F97;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x5B8C;&#x5168;&#x4F9D;&#x8D56;&#x5176;&#x65E0;&#x72B6;&#x6001;&#x7684;&#x7279;&#x6027;&#x63D0;&#x4F9B;&#x6570;&#x636E;API&#x670D;&#x52A1;&#xFF0C;&#x751A;&#x81F3;&#x662F;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x4E0B;&#x8F7D;&#x6D41;&#x670D;&#x52A1;&#x3002;</li>
<li>&#x56E0;&#x4E3A;JWT&#x5E76;&#x4E0D;&#x4F7F;&#x7528;Cookie&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4EFB;&#x4F55;&#x57DF;&#x540D;&#x63D0;&#x4F9B;&#x4F60;&#x7684;API&#x670D;&#x52A1;&#x800C;&#x4E0D;&#x9700;&#x8981;&#x62C5;&#x5FC3;&#x8DE8;&#x57DF;&#x8D44;&#x6E90;&#x5171;&#x4EAB;&#x95EE;&#x9898;&#xFF08;CORS&#xFF09;</li>
</ol>
<p><img src="http://img.zhufengpeixun.cn/JWT.png" alt="JWT"></p>
<h2 id="t115. JWT&#x5B9E;&#x6218;">5. JWT&#x5B9E;&#x6218; <a href="#t115. JWT&#x5B9E;&#x6218;"> # </a></h2>
<h3 id="t125.1 config.js">5.1 config.js <a href="#t125.1 config.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">dbUrl</span>: <span class="hljs-string">&apos;mongodb://127.0.0.1/jwt&apos;</span>,
    <span class="hljs-attr">secret</span>: <span class="hljs-string">&apos;zfpx&apos;</span>
}
</code></pre>
<h3 id="t135.2 app.js">5.2 app.js <a href="#t135.2 app.js"> # </a></h3>
<p><a href="http://momentjs.cn/">momentjs</a></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;express&apos;</span>);
<span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;jwt-simple&apos;</span>);
<span class="hljs-keyword">const</span> bodyParser = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;body-parser&apos;</span>);
<span class="hljs-keyword">const</span> moment = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;moment&apos;</span>);
<span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;./model/user&apos;</span>);
<span class="hljs-keyword">const</span> jwtWare = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;./jwt&apos;</span>);
<span class="hljs-keyword">const</span> { secret } = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;./config&apos;</span>);
<span class="hljs-keyword">const</span> app = express();
app.use(bodyParser.urlencoded({ <span class="hljs-attr">extended</span>: <span class="hljs-literal">true</span> }));
app.use(bodyParser.json());
app.post(<span class="hljs-string">&apos;/signup&apos;</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">req, res</span>) </span>{
    <span class="hljs-keyword">let</span> user = req.body;
    user = <span class="hljs-keyword">await</span> User.create(user);
    <span class="hljs-keyword">if</span> (user) {
        res.json({
            <span class="hljs-attr">code</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">data</span>: {
                user
            }
        });
    } <span class="hljs-keyword">else</span> {
        res.json({
            <span class="hljs-attr">code</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">data</span>: <span class="hljs-string">&apos;&#x7528;&#x6237;&#x6CE8;&#x518C;&#x5931;&#x8D25;&apos;</span>
        });
    }
});
app.post(<span class="hljs-string">&apos;/login&apos;</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">req, res</span>) </span>{
    <span class="hljs-keyword">let</span> user = req.body;
    user = <span class="hljs-keyword">await</span> User.findOne(user);
    <span class="hljs-keyword">if</span> (user) {
        <span class="hljs-keyword">let</span> expires = moment().add(<span class="hljs-number">7</span>, <span class="hljs-string">&apos;days&apos;</span>).valueOf();
        <span class="hljs-keyword">let</span> userInfo = {
            <span class="hljs-attr">id</span>: user._id,
            <span class="hljs-attr">username</span>: user.username
        };
        <span class="hljs-keyword">let</span> token = jwt.encode({
            <span class="hljs-attr">user</span>: userInfo,
            <span class="hljs-attr">exp</span>: expires
        }, secret);
        res.json({
            <span class="hljs-attr">code</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">data</span>: {
                token,
                expires,
                <span class="hljs-attr">user</span>: userInfo
            }
        });
    } <span class="hljs-keyword">else</span> {
        res.json({
            <span class="hljs-attr">code</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">data</span>: <span class="hljs-string">&apos;&#x7528;&#x6237;&#x540D;&#x6216;&#x5BC6;&#x7801;&#x9519;&#x8BEF;&apos;</span>
        });
    }
});
app.get(<span class="hljs-string">&apos;/user&apos;</span>, jwtWare, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">req, res</span>) </span>{
    res.json({
        <span class="hljs-attr">code</span>: <span class="hljs-number">0</span>,
        <span class="hljs-attr">data</span>: {
            <span class="hljs-attr">user</span>: req.user
        }
    });
});
app.listen(<span class="hljs-number">8080</span>);
</code></pre>
<h3 id="t145.3 jwt.js">5.3 jwt.js <a href="#t145.3 jwt.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { secret } = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;./config&apos;</span>);
<span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;jwt-simple&apos;</span>);
<span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;./model/user&apos;</span>);
<span class="hljs-built_in">module</span>.exports = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">req, res, next</span>) </span>{
    <span class="hljs-keyword">let</span> authorization = req.headers[<span class="hljs-string">&apos;authorization&apos;</span>];
    <span class="hljs-keyword">if</span> (authorization) {
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">let</span> decoded = jwt.decode(authorization.split(<span class="hljs-string">&apos; &apos;</span>)[<span class="hljs-number">1</span>], secret);
            req.user = decoded.user;
            next();
        } <span class="hljs-keyword">catch</span> (err) {
            <span class="hljs-built_in">console</span>.log(err);
            res.status(<span class="hljs-number">401</span>).send(<span class="hljs-string">&apos;Not Allowed&apos;</span>);
        }
    } <span class="hljs-keyword">else</span> {
        res.status(<span class="hljs-number">401</span>).send(<span class="hljs-string">&apos;Not Allowed&apos;</span>);
    }
}
</code></pre>
<h3 id="t155.4 user.js">5.4 user.js <a href="#t155.4 user.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;mongoose&apos;</span>);
<span class="hljs-keyword">let</span> Schema = mongoose.Schema;
<span class="hljs-keyword">let</span> ObjectId = Schema.Types.ObjectId;
<span class="hljs-keyword">let</span> { dbUrl } = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;../config&apos;</span>);
<span class="hljs-keyword">let</span> conn = mongoose.createConnection(dbUrl);
<span class="hljs-keyword">let</span> UserSchema = <span class="hljs-keyword">new</span> Schema({
    <span class="hljs-attr">username</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-built_in">String</span>
});
<span class="hljs-built_in">module</span>.exports = conn.model(<span class="hljs-string">&quot;User&quot;</span>, UserSchema);
</code></pre>
<h2 id="t166. &#x524D;&#x7AEF;">6. &#x524D;&#x7AEF; <a href="#t166. &#x524D;&#x7AEF;"> # </a></h2>
<pre><code class="lang-js">create-react-app front
cd front
cnpm i react react-dom react-router-dom axios -S
</code></pre>
<h3 id="t176.1 index.js">6.1 index.js <a href="#t176.1 index.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-dom&apos;</span>;
<span class="hljs-keyword">import</span> { Router, Route, Switch, Redirect } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-router-dom&apos;</span>;
<span class="hljs-keyword">import</span> createHashHistory <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;history/createHashHistory&apos;</span>;
<span class="hljs-keyword">import</span> Login <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./components/Login&apos;</span>;
<span class="hljs-keyword">import</span> User <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./components/User&apos;</span>;
<span class="hljs-keyword">const</span> history = createHashHistory();
ReactDOM.render(
    &lt;Router history={history}&gt;
        &lt;Switch&gt;
            &lt;Route exact path=&quot;/&quot; component={Login} /&gt;
            &lt;Route path=&quot;/user&quot; component={User} /&gt;
            &lt;Redirect to=&quot;/&quot; /&gt;
        &lt;/Switch&gt;
    &lt;/Router&gt;, document.querySelector(&apos;#root&apos;)
);
</code></pre>
<h3 id="t186.2 api.js">6.2 api.js <a href="#t186.2 api.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;axios&apos;</span>;
<span class="hljs-keyword">import</span> createHashHistory <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;history/createHashHistory&apos;</span>;
<span class="hljs-keyword">const</span> history = createHashHistory();
axios.interceptors.request.use(<span class="hljs-function"><span class="hljs-params">config</span> =&gt;</span> {
    <span class="hljs-keyword">if</span> (localStorage.token) {
        config.headers.Authorization = <span class="hljs-string">&apos;Bearer &apos;</span> + localStorage.token
    }
    <span class="hljs-keyword">return</span> config
}, error =&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.reject(error)
})

axios.interceptors.response.use(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> {
    <span class="hljs-keyword">if</span> (res.data.code != <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.reject(res);
    }
    <span class="hljs-keyword">return</span> res;
}, error =&gt; {
    <span class="hljs-keyword">if</span> (error.response.status == <span class="hljs-number">401</span>) {
        history.push(<span class="hljs-string">&apos;/&apos;</span>);
    }
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.reject(error.response.data);
});

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">login</span>(<span class="hljs-params">data</span>) </span>{
    <span class="hljs-keyword">return</span> axios({
        <span class="hljs-attr">url</span>: <span class="hljs-string">&apos;http://localhost:8080/login&apos;</span>,
        <span class="hljs-attr">method</span>: <span class="hljs-string">&apos;post&apos;</span>,
        data
    }).then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> {
        <span class="hljs-keyword">let</span> data = response.data;
        localStorage.setItem(<span class="hljs-string">&apos;token&apos;</span>, data.data.token);
        <span class="hljs-keyword">return</span> data;
    })
}
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUser</span>(<span class="hljs-params">data</span>) </span>{
    <span class="hljs-keyword">return</span> axios({
        <span class="hljs-attr">url</span>: <span class="hljs-string">&apos;http://localhost:8080/user&apos;</span>,
        <span class="hljs-attr">method</span>: <span class="hljs-string">&apos;get&apos;</span>
    }).then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> {
        <span class="hljs-keyword">return</span> response.data;
    })
}
</code></pre>
<h3 id="t196.3 Login.js">6.3 Login.js <a href="#t196.3 Login.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> { login } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../api&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Login</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
    handleSubmit = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
        event.preventDefault();
        <span class="hljs-keyword">let</span> username = <span class="hljs-keyword">this</span>.username.value;
        <span class="hljs-keyword">let</span> password = <span class="hljs-keyword">this</span>.password.value;
        login({ username, password }).then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> {
            <span class="hljs-keyword">if</span> (data.code == <span class="hljs-number">0</span>) {
                <span class="hljs-keyword">this</span>.props.history.push(<span class="hljs-string">&apos;/user&apos;</span>);
            }
        });
    }
    render() {
        <span class="hljs-keyword">return</span> (
            &lt;form onSubmit={this.handleSubmit}&gt;
                &#x7528;&#x6237;&#x540D;&lt;input required ref={ref =&gt; this.username = ref} /&gt;
                &#x5BC6;&#x7801;&lt;input required ref={ref =&gt; this.password = ref} /&gt;
                &lt;input type=&quot;submit&quot; /&gt;
            &lt;/form&gt;
        )
    }
}
</code></pre>
<h3 id="t206.4 User.js">6.4 User.js <a href="#t206.4 User.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> { getUser } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../api&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
    state = {
        <span class="hljs-attr">user</span>: {}
    }
    componentDidMount() {
        getUser().then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> {
            <span class="hljs-keyword">if</span> (res &amp;&amp; res.code == <span class="hljs-number">0</span>) {
                <span class="hljs-keyword">this</span>.setState({ <span class="hljs-attr">user</span>: res.data.user });
            }
        });
    }
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                &#x6B22;&#x8FCE; {this.state.user.username}
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        )
    }
}
</code></pre>
<h2 id="t217.&#x539F;&#x7406;&#x5B9E;&#x73B0;">7.&#x539F;&#x7406;&#x5B9E;&#x73B0; <a href="#t217.&#x539F;&#x7406;&#x5B9E;&#x73B0;"> # </a></h2>
<p>jwt.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> crypto = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;crypto&apos;</span>);
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">encode</span>(<span class="hljs-params">payload, key</span>) </span>{
    <span class="hljs-keyword">let</span> header = { <span class="hljs-attr">type</span>: <span class="hljs-string">&apos;JWT&apos;</span>, <span class="hljs-attr">alg</span>: <span class="hljs-string">&apos;sha256&apos;</span> };<span class="hljs-comment">//&#x58F0;&#x660E;&#x7C7B;&#x578B;&#x548C;&#x7B97;&#x6CD5;</span>
    <span class="hljs-keyword">var</span> segments = [];<span class="hljs-comment">//&#x58F0;&#x660E;&#x4E00;&#x4E2A;&#x6570;&#x7EC4;</span>
    segments.push(base64urlEncode(<span class="hljs-built_in">JSON</span>.stringify(header)));<span class="hljs-comment">//&#x5BF9;header&#x8FDB;&#x884C;base64</span>
    segments.push(base64urlEncode(<span class="hljs-built_in">JSON</span>.stringify(payload)));<span class="hljs-comment">//&#x5BF9;&#x8D1F;&#x8F7D;&#x8FDB;&#x884C;base64</span>
    segments.push(sign(segments.join(<span class="hljs-string">&apos;.&apos;</span>), key));<span class="hljs-comment">//&#x52A0;&#x5165;&#x7B7E;&#x540D;</span>
    <span class="hljs-keyword">return</span> segments.join(<span class="hljs-string">&apos;.&apos;</span>);
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sign</span>(<span class="hljs-params">input, key</span>) </span>{
    <span class="hljs-keyword">return</span> crypto.createHmac(<span class="hljs-string">&apos;sha256&apos;</span>, key).update(input).digest(<span class="hljs-string">&apos;base64&apos;</span>);
}


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">decode</span>(<span class="hljs-params">token, key</span>) </span>{
    <span class="hljs-keyword">var</span> segments = token.split(<span class="hljs-string">&apos;.&apos;</span>);
    <span class="hljs-keyword">var</span> headerSeg = segments[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">var</span> payloadSeg = segments[<span class="hljs-number">1</span>];
    <span class="hljs-keyword">var</span> signatureSeg = segments[<span class="hljs-number">2</span>];

    <span class="hljs-keyword">var</span> header = <span class="hljs-built_in">JSON</span>.parse(base64urlDecode(headerSeg));
    <span class="hljs-keyword">var</span> payload = <span class="hljs-built_in">JSON</span>.parse(base64urlDecode(payloadSeg));

    <span class="hljs-keyword">if</span> (signatureSeg != sign([headerSeg, payloadSeg].join(<span class="hljs-string">&apos;.&apos;</span>), key)) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">&apos;verify failed&apos;</span>);
    }

    <span class="hljs-keyword">if</span> (payload.exp &amp;&amp; <span class="hljs-built_in">Date</span>.now() &gt; payload.exp * <span class="hljs-number">1000</span>) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">&apos;Token expired&apos;</span>);
    }
    <span class="hljs-keyword">return</span> payload;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">base64urlEncode</span>(<span class="hljs-params">str</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Buffer(str).toString(<span class="hljs-string">&apos;base64&apos;</span>);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">base64urlDecode</span>(<span class="hljs-params">str</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Buffer(str, <span class="hljs-string">&apos;base64&apos;</span>).toString();
}

<span class="hljs-built_in">module</span>.exports = {
    encode,
    decode
}
</code></pre>

        <div class="copyright">Powered by <a href="https://github.com/jaywcjlove/idoc" target="_blank">idoc</a>. Dependence <a href="https://nodejs.org">Node.js</a> run.</div>
    </div>
    
</div>

<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.js"></script>
<script>
$('.warpper .page-toc ul ul li a').on('click',function(){
  $('.warpper .page-toc ul ul li a').removeClass('my-active')
  $(this).addClass('my-active')
})
  // if (!$('.understand-me').length) {
  //   var bar = $(window).height() - $('.navbar ').height() - $('.page-toc').position().top;
  //   var count = bar / 26 / 2;
  //   var barHeight = $('.page-toc').outerHeight();
  //   $('.page-toc li').eq(0).children('a').addClass('red');
  //   var arr = [];
  //   $("h1,h2,h3,h4,h5,h6").each(function () {
  //     arr.push($(this).position().top);
  //   });
  //   var timer
  //   function dark() {
  //     clearTimeout(timer)
  //      timer = setTimeout(function () {
  //      var top = Math.abs($('.page-toc > ul').position().top);
  //      var cur = $('.content').scrollTop();
  //      for (var i = arr.length; i >= 0; i--) {
  //        if (arr[i] <= cur) {
  //          break;
  //        }
  //      }
  //      if (i === -1) {
  //        i = 0;
  //      }
  //      $('.page-toc li a').removeClass('red');
  //      $('.page-toc li').eq(i).children('a').addClass('red');
  //      let height = $('.page-toc li').eq(i).position().top-$('.page-toc').height(); // 如果当前的offset出去了 回到中间可好？
  //      $('.page-toc').scrollTop(height+$('.page-toc').height()/2);
  //    },200)
  //   }

  //   $('.content').on('scroll', dark);
  // }
</script>
<style>

    /* ::-webkit-scrollbar{width:14px;}
    ::-webkit-scrollbar-track{background-color:transparent;}
    ::-webkit-scrollbar-thumb{background-color:transparent;}
    ::-webkit-scrollbar-thumb:hover {background-color:transparent}
    ::-webkit-scrollbar-thumb:active {background-color:transparent} */

    .page-toc > ul .red {
        background: #f3f3f3;
        z-index: 1;
        border-left: 3px solid #009a61;
        -webkit-transition: all .2s ease;
        transition: all .2s ease;
        color: #000
    }





</style>
</body>
</html>
